package com.xyht.sca_s.student_manage_system.modules.newTips.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.SmsNewTips;
import com.xyht.sca_s.student_manage_system.modules.newTips.entity.SmsNewTipsRecord;
import com.xyht.sca_s.student_manage_system.modules.newTips.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.*;
import com.xyht.sca_s.student_manage_system.modules.newTips.service.SmsNewTipsRecordService;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgUserRelation;
import com.xyht.sca_s.student_manage_system.modules.tips.entity.resp.SmsUserAndOrgRelationResp;
import com.xyht.sca_s.student_manage_system.modules.tips.entity.resp.SmsUserAndRoleRelationResp;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsApplication;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUserRoleRelation;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsApplicationMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import com.xyht.sca_s.student_manage_system.modules.websocket.entity.WebsocketResult;
import com.xyht.sca_s.student_manage_system.modules.websocket.service.WebSocketService;
import com.xyht.sca_s.student_manage_system.modules.wx.myEnum.MessageEventEnum;
import com.xyht.sca_s.student_manage_system.modules.wx.myEnum.MessageStepEnum;
import com.xyht.sca_s.student_manage_system.modules.wx.util.WeChatUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.IsCloseFlagConstant.TIPS_CLOSE_FLAG_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.IsCloseFlagConstant.TIPS_CLOSE_FLAG_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.IsReadFlagConstant.TIPS_READ_FLAG_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.NewTipsCloseFlagConstant.TIPS_OPEN;
import static com.xyht.sca_s.student_manage_system.modules.newTips.constant.RangeTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.CopyTypeEnum.COPY_TYPE_ENUM_NONE;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum.RANGE_TYPE_ENUM_ALL;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum.RANGE_TYPE_ENUM_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsRecordStatusEnum.*;
import static com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum.*;
import static com.xyht.sca_s.student_manage_system.modules.websocket.myEnum.WebsocketResultEnum.TIPS_INFORM;

@Component
@Log4j2
public class NewTipsUtil {
    @Resource
    private SmsNewTipsMapper smsNewTipsMapper;

    @Resource
    private SmsUserMapper smsUserMapper;

    @Resource
    private SmsUserAndOrgMpjMapper smsUserAndOrgMpjMapper;

    @Resource
    private SmsUserAndRoleMpjMapper smsUserAndRoleMpjMapper;

    @Resource
    private SmsNewTipsRecordMpjMapper smsNewTipsRecordMpjMapper;

    @Resource
    private SmsNewTipsRecordService smsNewTipsRecordService;

    @Resource
    private WebSocketService webSocketService;

    @Resource
    private SmsNewTipsRecordMapper smsNewTipsRecordMapper;

    @Resource
    private WeChatUtil weChatUtil;

    @Resource
    private SmsApplicationMapper smsApplicationMapper;

    /**
     * 重载方法 无过期时间 无抄送人 无消息分类类型
     * 添加新的消息通知或审批通知
     *
     * @param tipsTypeEnum  消息通知的类型  1：消息   2：待办   3：审批
     * @param apply_user_id 产生本次消息通知的人的id，同时也是审批的提交人
     * @param rangeTypeEnum 消息通知范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param range_id_list 消息通知范围的id集合 例：如通知范围为角色通知，则当前就为所通知角色id的集合
     * @param appTypeEnum   应用类型
     * @param event_id      消息通知绑定的事件id 消息类型为消息时，可不填 例：如消息类型为审批，则event_id就为申请表id
     */
    @Transactional
    public void addNewTips(TipsTypeEnum tipsTypeEnum,
                           String apply_user_id,
                           RangeTypeEnum rangeTypeEnum,
                           List<String> range_id_list,
                           AppTypeEnum appTypeEnum,
                           String event_id,
                           String process_detail_id
    ) {
        addNewTips(tipsTypeEnum, apply_user_id, rangeTypeEnum, range_id_list, COPY_TYPE_ENUM_NONE, null, appTypeEnum, event_id, null, null, process_detail_id, null, "", "","");
    }

    /**
     * 重载方法 动态应用使用
     */
    @Transactional
    public void addNewTips(TipsTypeEnum tipsTypeEnum,
                           String apply_user_id,
                           RangeTypeEnum rangeTypeEnum,
                           List<String> range_id_list,
                           String event_id,
                           String process_detail_id,
                           String dynamic_app_type,
                           String dynamic_app_name
    ) {
        addNewTips(tipsTypeEnum, apply_user_id, rangeTypeEnum, range_id_list, COPY_TYPE_ENUM_NONE, null, null, event_id, null, null, process_detail_id, null, dynamic_app_type, dynamic_app_name,"");
    }

    @Transactional
    public void addNewTips(TipsTypeEnum tipsTypeEnum,
                           String apply_user_id,
                           RangeTypeEnum rangeTypeEnum,
                           List<String> range_id_list,
                           AppTypeEnum appTypeEnum,
                           String event_id,
                           String process_detail_id,
                           String send_mp_content,
                           TipsRecordStatusEnum tipsRecordStatusEnum
    ) {
        addNewTips(tipsTypeEnum, apply_user_id, rangeTypeEnum, range_id_list, COPY_TYPE_ENUM_NONE, null, appTypeEnum, event_id, null, tipsRecordStatusEnum, process_detail_id, send_mp_content, "", "","");
    }

    /**
     * 重载方法 无过期时间 无抄送人
     * 添加新的消息通知或审批通知
     *
     * @param tipsTypeEnum         消息通知的类型  1：消息   2：待办   3：审批
     * @param apply_user_id        产生本次消息通知的人的id，同时也是审批的提交人
     * @param rangeTypeEnum        消息通知范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param range_id_list        消息通知范围的id集合 例：如通知范围为角色通知，则当前就为所通知角色id的集合
     * @param appTypeEnum          应用类型
     * @param event_id             消息通知绑定的事件id 消息类型为消息时，可不填 例：如消息类型为审批，则event_id就为申请表id
     * @param tipsRecordStatusEnum 消息分类类型，当消息为消息类型时可用 选填
     */
    @Transactional
    public void addNewTips(TipsTypeEnum tipsTypeEnum,
                           String apply_user_id,
                           RangeTypeEnum rangeTypeEnum,
                           List<String> range_id_list,
                           AppTypeEnum appTypeEnum,
                           String event_id,
                           TipsRecordStatusEnum tipsRecordStatusEnum,
                           String process_detail_id
    ) {
        addNewTips(tipsTypeEnum, apply_user_id, rangeTypeEnum, range_id_list, COPY_TYPE_ENUM_NONE, null, appTypeEnum, event_id, null, tipsRecordStatusEnum, process_detail_id, null, "", "","");
    }

    /**
     * 重载方法 无过期时间
     * 添加新的消息通知或审批通知
     *
     * @param tipsTypeEnum         消息通知的类型  1：消息   2：待办   3：审批
     * @param apply_user_id        产生本次消息通知的人的id，同时也是审批的提交人
     * @param rangeTypeEnum        消息通知范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param range_id_list        消息通知范围的id集合 例：如通知范围为角色通知，则当前就为所通知角色id的集合
     * @param copyTypeEnum         消息通知抄送范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param copy_id_list         消息通知抄送范围id集合
     * @param appTypeEnum          应用类型
     * @param event_id             消息通知绑定的事件id 消息类型为消息时，可不填 例：如消息类型为审批，则event_id就为申请表id
     * @param tipsRecordStatusEnum 消息分类类型，当消息为消息类型时可用 选填
     */
    @Transactional
    public void addNewTips(TipsTypeEnum tipsTypeEnum,
                           String apply_user_id,
                           RangeTypeEnum rangeTypeEnum,
                           List<String> range_id_list,
                           CopyTypeEnum copyTypeEnum,
                           List<String> copy_id_list,
                           AppTypeEnum appTypeEnum,
                           String event_id,
                           TipsRecordStatusEnum tipsRecordStatusEnum,
                           String process_detail_id
    ) {
        addNewTips(tipsTypeEnum, apply_user_id, rangeTypeEnum, range_id_list, copyTypeEnum, copy_id_list, appTypeEnum, event_id, null, tipsRecordStatusEnum, process_detail_id, null, "", "","");
    }

    /**
     * 添加新的消息通知或审批通知
     *
     * @param tipsTypeEnum         消息通知的类型  1：消息   2：待办   3：审批
     * @param apply_user_id        产生本次消息通知的人的id，同时也是审批的提交人
     * @param rangeTypeEnum        消息通知范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param range_id_list        消息通知范围的id集合 例：如通知范围为角色通知，则当前就为所通知角色id的集合
     * @param copyTypeEnum         消息通知抄送范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param copy_id_list         消息通知抄送范围id集合
     * @param appTypeEnum          应用类型
     * @param event_id             消息通知绑定的事件id 消息类型为消息时，可不填 例：如消息类型为审批，则event_id就为申请表id
     * @param expire_time          过期时间 选填
     * @param tipsRecordStatusEnum 消息分类类型，当消息为消息类型时可用 选填
     * @param process_detail_id    流程节点id 消息类型为审批时可用
     * @param message_content      自定义消息内容
     */
    @Transactional
    public void addNewTips(TipsTypeEnum tipsTypeEnum,
                           String apply_user_id,
                           RangeTypeEnum rangeTypeEnum,
                           List<String> range_id_list,
                           CopyTypeEnum copyTypeEnum,
                           List<String> copy_id_list,
                           AppTypeEnum appTypeEnum,
                           String event_id,
                           Date expire_time,
                           TipsRecordStatusEnum tipsRecordStatusEnum,
                           String process_detail_id,
                           String send_mp_content,
                           String dynamic_app_type,
                           String dynamic_app_name,
                           String message_content
    ) {
        if (range_id_list == null && copy_id_list == null) {
            return;
        }
        try {
            SmsNewTips smsNewTips = new SmsNewTips();
            smsNewTips.setTipsType(tipsTypeEnum.getValue());
            smsNewTips.setTipsCreator(apply_user_id);
            if (range_id_list != null && range_id_list.size() > 0) {
                smsNewTips.setTipsRangeType(rangeTypeEnum.getValue());
                smsNewTips.setTipsRange(JSON.toJSONString(range_id_list));
            }
            if (copy_id_list != null && copy_id_list.size() > 0) {
                smsNewTips.setTipsCopyType(copyTypeEnum.getValue());
                smsNewTips.setTipsCopy(JSON.toJSONString(copy_id_list));
            }
            smsNewTips.setAppType(appTypeEnum == null ? dynamic_app_type : appTypeEnum.getValue());
            smsNewTips.setEventId(event_id);
            smsNewTips.setExpirationTime(expire_time);
            smsNewTips.setTipsContent(message_content);
            smsNewTipsMapper.insert(smsNewTips);

            //添加到对应个人消息待办关系表
            List<String> userIDList;
            List<String> copyUserIDList = new ArrayList<>();
            if (smsNewTips.getTipsRangeType() == RANGE_TYPE_ENUM_ALL.getValue()) {
                //添加所有人到关系表
                QueryWrapper<SmsUser> userQueryWrapper = new QueryWrapper<>();
//                if (user_type != USER_TYPE_ALL) {
//                    userQueryWrapper.lambda().eq(SmsUser::getFlag, user_type);
//                }
                List<SmsUser> smsUserList = smsUserMapper.selectList(userQueryWrapper);
                userIDList = smsUserList.stream().map(SmsUser::getId).collect(Collectors.toList());
            } else {
                //消息推送用户
                userIDList = queryUserIDList(smsNewTips.getTipsRangeType(), smsNewTips.getTipsRange());
                //消息抄送用户
                if (copyTypeEnum != null && copyTypeEnum.getValue() != COPY_TYPE_ENUM_NONE.getValue()
                        && copy_id_list != null && copy_id_list.size() > 0) {
                    copyUserIDList = queryUserIDList(smsNewTips.getTipsCopyType(), smsNewTips.getTipsCopy());
                }
            }

            //保存消息创建用户 流程创建用户才保存
            if (smsNewTips.getTipsType() == TIPS_TYPE_ENUM_ALLOW.getValue()) {
                SmsNewTipsRecord createUserRecord = new SmsNewTipsRecord();
                createUserRecord.setRecordUserId(smsNewTips.getTipsCreator());
                createUserRecord.setRecordTipsId(smsNewTips.getId());
                createUserRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue());
                createUserRecord.setIsRead(TIPS_READ_FLAG_FALSE);
                createUserRecord.setRecordContent(message_content);

                smsNewTipsRecordMapper.insert(createUserRecord);
            }

            //保存消息通知用户
            if (userIDList.size() > 0) {
                List<SmsNewTipsRecord> saveRecord = new ArrayList<>();
                for (String user_id : userIDList) {
                    SmsNewTipsRecord smsTipsRecord = new SmsNewTipsRecord();
                    smsTipsRecord.setRecordContent(message_content);
                    smsTipsRecord.setRecordUserId(user_id);
                    smsTipsRecord.setRecordTipsId(smsNewTips.getId());
                    if (smsNewTips.getTipsType() == TIPS_TYPE_ENUM_MESSAGE.getValue()) {
                        if (tipsRecordStatusEnum != null) {
                            smsTipsRecord.setRecordStatus(tipsRecordStatusEnum.getValue());
                        }

                        //发送公众号模板消息
                        weChatUtil.sendWXMPTemplateMessage(apply_user_id,
                                user_id,
                                appTypeEnum == null ? dynamic_app_name : appTypeEnum.getName(),
                                MessageEventEnum.MESSAGE_EVENT_ENUM_MSG,
                                MessageStepEnum.MESSAGE_STEP_ENUM_WAIT_CHECK,
                                isNullOrEmpty(send_mp_content) ? "你有一条消息待查看" : send_mp_content);
                    } else if (smsNewTips.getTipsType() == TIPS_TYPE_ENUM_DEAL.getValue()) {
                        smsTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue());

                        //发送公众号模板消息
                        weChatUtil.sendWXMPTemplateMessage(apply_user_id,
                                user_id,
                                appTypeEnum == null ? dynamic_app_name : appTypeEnum.getName(),
                                MessageEventEnum.MESSAGE_EVENT_ENUM_DEAL,
                                MessageStepEnum.MESSAGE_STEP_ENUM_WAIT_DEAL,
                                null);
                    } else {
                        smsTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue());

                        //发送公众号模板消息
                        weChatUtil.sendWXMPTemplateMessage(apply_user_id,
                                user_id,
                                appTypeEnum == null ? dynamic_app_name : appTypeEnum.getName(),
                                MessageEventEnum.MESSAGE_EVENT_ENUM_ALLOW,
                                MessageStepEnum.MESSAGE_STEP_ENUM_WAIT_ALLOW,
                                null);
                    }
                    smsTipsRecord.setIsRead(TIPS_READ_FLAG_FALSE);
                    if (tipsTypeEnum == TIPS_TYPE_ENUM_ALLOW) {
                        smsTipsRecord.setProcessDetailId(process_detail_id);
                    }

                    saveRecord.add(smsTipsRecord);
                }
                smsNewTipsRecordService.saveBatch(saveRecord);
                //发送界面更新消息
                webSocketService.batchSend(userIDList, null, WebsocketResult.success(TIPS_INFORM));
            }

            //保存抄送用户
            if (copyUserIDList.size() > 0) {
                List<SmsNewTipsRecord> saveRecord = new ArrayList<>();
                for (String user_id : copyUserIDList) {
                    SmsNewTipsRecord smsTipsRecord = new SmsNewTipsRecord();
                    smsTipsRecord.setRecordContent(message_content);
                    smsTipsRecord.setRecordUserId(user_id);
                    smsTipsRecord.setRecordTipsId(smsNewTips.getId());
                    smsTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_COPY.getValue());
                    smsTipsRecord.setIsRead(TIPS_READ_FLAG_FALSE);

                    saveRecord.add(smsTipsRecord);

                    //发送公众号模板消息
                    weChatUtil.sendWXMPTemplateMessage(apply_user_id,
                            user_id,
                            appTypeEnum == null ? dynamic_app_name : appTypeEnum.getName(),
                            MessageEventEnum.MESSAGE_EVENT_ENUM_COPY_MSG,
                            MessageStepEnum.MESSAGE_STEP_ENUM_COPY_WAIT_CHECK,
                            null);

                }
                smsNewTipsRecordService.saveBatch(saveRecord);
                //发送界面更新消息
                webSocketService.batchSend(copyUserIDList, null, WebsocketResult.success(TIPS_INFORM));
            }

        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    private List<String> queryUserIDList(Integer rangeType, String range) {
        List<String> userIDList = new ArrayList<>();
        List<String> rangeList = JSONObject.parseArray(range, String.class);
        if (rangeList != null && rangeList.size() > 0) {
            switch (rangeType) {
                //添加指定人到关系表
                case RANGE_TYPE_PERSON:
                    userIDList = rangeList;
                    break;
                //添加指定组织中的人到关系表
                case RANGE_TYPE_ORG:
                    MPJLambdaWrapper<SmsOrgUserRelation> mpjLambdaWrapper = new MPJLambdaWrapper<>();
                    mpjLambdaWrapper.selectAll(SmsOrgUserRelation.class)
                            .selectAll(SmsUser.class)
                            .leftJoin(SmsUser.class, SmsUser::getId, SmsOrgUserRelation::getUserId)
                            .in(SmsOrgUserRelation::getOrgId, rangeList);
//                            if (user_type != USER_TYPE_ALL) {
//                                mpjLambdaWrapper.eq(SmsUser::getFlag, user_type);
//                            }
                    List<SmsUserAndOrgRelationResp> smsUserOrgList = smsUserAndOrgMpjMapper.selectJoinList(SmsUserAndOrgRelationResp.class, mpjLambdaWrapper);
                    userIDList = smsUserOrgList.stream().map(SmsUserAndOrgRelationResp::getUserId).collect(Collectors.toList());
                    break;
                //添加指定角色中的人到关系表
                case RANGE_TYPE_ROLE:
                    MPJLambdaWrapper<SmsUserRoleRelation> mpjWrapper = new MPJLambdaWrapper<>();
                    mpjWrapper.selectAll(SmsUserRoleRelation.class)
                            .selectAll(SmsUser.class)
//                                    .selectAs(SmsUserRoleRelation::getUserId,"id")
                            .selectAs(SmsOrgUserRelation::getId, "relation_id")
                            .leftJoin(SmsUser.class, SmsUser::getId, SmsUserRoleRelation::getUserId)
                            .in(SmsUserRoleRelation::getRoleId, rangeList);
//                            if (user_type != USER_TYPE_ALL) {
//                                mpjWrapper.eq(SmsUser::getFlag, user_type);
//                            }
                    List<SmsUserAndRoleRelationResp> smsUserRoleList = smsUserAndRoleMpjMapper.selectJoinList(SmsUserAndRoleRelationResp.class, mpjWrapper);
                    userIDList = smsUserRoleList.stream().map(SmsUserAndRoleRelationResp::getUserId).collect(Collectors.toList());
                    break;
            }
        }
        return userIDList;
    }


    /**
     * 已有消息通知，继续审批通知流程，消息类型必须为审批
     * 此方法默认当前节点流程审批通过！！！
     * 此方法默认当前节点流程审批通过！！！
     * 此方法默认当前节点流程审批通过！！！
     *
     * @param event_id          消息通知绑定的事件id 消息类型为消息时，可不填 例：如消息类型为审批，则event_id就为申请表id
     * @param allow_user_id     当前审批人id（若为强制流转，则不需要传此参数）
     * @param rangeTypeEnum     消息通知范围类型 0：全通知  1：个人通知  2：角色通知  3：组织通知
     * @param range_id_list     消息通知范围的id集合 例：如通知范围为角色通知，则当前就为所通知角色id的集合
     * @param process_detail_id 流程节点id 消息类型为审批时可用
     */
    @Transactional
    public void allowContinueTips(String event_id,
                                  String allow_user_id,
                                  RangeTypeEnum rangeTypeEnum,
                                  List<String> range_id_list,
                                  String process_detail_id
    ) {
        try {
            //查看消息是否存在且是否为审批消息类型
            SmsNewTips smsNewTips = smsNewTipsMapper.selectOne(new QueryWrapper<SmsNewTips>()
                    .lambda()
                    .eq(SmsNewTips::getEventId, event_id)
                    .eq(SmsNewTips::getIsClose, TIPS_OPEN)
                    .eq(SmsNewTips::getTipsType, TIPS_TYPE_ENUM_ALLOW.getValue()));
            if (smsNewTips == null || isNullOrEmpty(smsNewTips.getId())
                    || smsNewTips.getTipsType() != TIPS_TYPE_ENUM_ALLOW.getValue()) {
                return;
            }

            //判断allow_user_id审批人是否存在,否则跳过以下操作
            if (!isNullOrEmpty(allow_user_id)) {
                //查看操作人记录是否存在
                SmsNewTipsRecord smsNewTipsRecord = smsNewTipsRecordMapper.selectOne(new QueryWrapper<SmsNewTipsRecord>()
                        .lambda()
                        .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                        .eq(SmsNewTipsRecord::getRecordUserId, allow_user_id)
                        .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue()));
                if (smsNewTipsRecord != null && !isNullOrEmpty(smsNewTipsRecord.getId())) {
                    //修改审批人状态
                    SmsNewTipsRecord updateTipsRecord = new SmsNewTipsRecord();
                    updateTipsRecord.setId(smsNewTipsRecord.getId());
                    updateTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME_FINISH.getValue());
                    smsNewTipsRecordMapper.updateById(updateTipsRecord);
                }
            }
            //删除其他审批人
            smsNewTipsRecordMapper.delete(new QueryWrapper<SmsNewTipsRecord>()
                    .lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue()));

            //添加到对应个人消息待办关系表
            List<String> userIDList = new ArrayList<>();
            if (smsNewTips.getTipsRangeType() == RANGE_TYPE_ENUM_ALL.getValue()) {
                //添加所有人到关系表
                QueryWrapper<SmsUser> userQueryWrapper = new QueryWrapper<>();
//                if (user_type != USER_TYPE_ALL) {
//                    userQueryWrapper.lambda().eq(SmsUser::getFlag, user_type);
//                }
                List<SmsUser> smsUserList = smsUserMapper.selectList(userQueryWrapper);
                userIDList = smsUserList.stream().map(SmsUser::getId).collect(Collectors.toList());
            } else {
                //消息推送用户
                if (range_id_list != null && range_id_list.size() > 0) {
                    userIDList = queryUserIDList(rangeTypeEnum.getValue(), JSONObject.toJSONString(range_id_list));
                }
            }

            //保存消息通知用户
            if (userIDList.size() > 0) {
                List<SmsNewTipsRecord> saveRecord = new ArrayList<>();
                for (String user_id : userIDList) {
                    SmsNewTipsRecord smsTipsRecord = new SmsNewTipsRecord();
                    smsTipsRecord.setRecordUserId(user_id);
                    smsTipsRecord.setRecordTipsId(smsNewTips.getId());
                    smsTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue());
                    smsTipsRecord.setIsRead(TIPS_READ_FLAG_FALSE);
                    smsTipsRecord.setProcessDetailId(process_detail_id);
                    smsTipsRecord.setRecordContent(smsNewTips.getTipsContent());

                    saveRecord.add(smsTipsRecord);

                    //发送公众号模板消息
                    String appName = "";
                    List<AppTypeEnum> appTypeEnum = Arrays.asList(AppTypeEnum.values()).stream()
                            .filter(app -> app.getValue().equals(smsNewTips.getAppType()))
                            .collect(Collectors.toList());

                    if (appTypeEnum.size() < 1) {
                        List<SmsApplication> applicationList = smsApplicationMapper.selectList(new LambdaQueryWrapper<SmsApplication>()
                                .eq(SmsApplication::getAppType, smsNewTips.getAppType()));
                        if (applicationList != null && applicationList.size() > 0) {
                            appName = applicationList.get(0).getAppName();
                        }
                    }else {
                        appName = appTypeEnum.get(0).getName();
                    }

                    weChatUtil.sendWXMPTemplateMessage(smsNewTips.getTipsCreator(),
                            user_id,
                            appName,
                            MessageEventEnum.MESSAGE_EVENT_ENUM_ALLOW,
                            MessageStepEnum.MESSAGE_STEP_ENUM_WAIT_ALLOW,
                            null);
                }
                smsNewTipsRecordService.saveBatch(saveRecord);
                //发送界面更新消息
                webSocketService.batchSend(userIDList, null, WebsocketResult.success(TIPS_INFORM));
            }


        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * 已有消息通知，结束审批通知流程，消息类型必须为审批
     * 审批流程结束或驳回申请调用此方法
     *
     * @param event_id      消息通知绑定的事件id  例：如消息类型为审批，则event_id就为申请表id
     * @param allow_user_id 审批人id
     * @param allow_result  审批结果  true：通过  false：不通过
     */
    @Transactional
    public void allowFinishTips(String event_id,
                                String allow_user_id,
                                Boolean allow_result
    ) {
        try {
            //查看消息是否存在且是否为审批消息类型 消息为开启状态
            SmsNewTips smsNewTips = smsNewTipsMapper.selectOne(new QueryWrapper<SmsNewTips>()
                    .lambda()
                    .eq(SmsNewTips::getEventId, event_id)
                    .eq(SmsNewTips::getIsClose, TIPS_OPEN)
                    .eq(SmsNewTips::getTipsType, TIPS_TYPE_ENUM_ALLOW.getValue()));
            if (smsNewTips == null || isNullOrEmpty(smsNewTips.getId())
                    || smsNewTips.getTipsType() != TIPS_TYPE_ENUM_ALLOW.getValue()) {
                return;
            }

            //查看操作人记录是否存在
            SmsNewTipsRecord smsNewTipsRecord = smsNewTipsRecordMapper.selectOne(new QueryWrapper<SmsNewTipsRecord>()
                    .lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordUserId, allow_user_id)
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue()));
            if (smsNewTipsRecord == null || isNullOrEmpty(smsNewTipsRecord.getId())) {
                return;
            }

            //修改消息状态
            SmsNewTips updateNewTips = new SmsNewTips();
            updateNewTips.setId(smsNewTips.getId());
            updateNewTips.setIsClose(TIPS_CLOSE_FLAG_TRUE);
            smsNewTipsMapper.updateById(updateNewTips);


            //修改审批人状态 删除其他审批人
            SmsNewTipsRecord updateTipsRecord = new SmsNewTipsRecord();
            updateTipsRecord.setId(smsNewTipsRecord.getId());
            updateTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME_FINISH.getValue());
            smsNewTipsRecordMapper.updateById(updateTipsRecord);

            smsNewTipsRecordMapper.delete(new QueryWrapper<SmsNewTipsRecord>()
                    .lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue()));

            //修改申请人状态
            SmsNewTipsRecord updateApplyTipsRecord = new SmsNewTipsRecord();
            if (allow_result) {
                updateApplyTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_ALLOWING_FINISH.getValue());
            } else {
                updateApplyTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_REJECTED.getValue());
            }
            smsNewTipsRecordMapper.update(updateApplyTipsRecord, new QueryWrapper<SmsNewTipsRecord>()
                    .lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordUserId, smsNewTips.getTipsCreator())
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue()));

            //发送公众号模板消息
            String appName = "";
            List<AppTypeEnum> list = Arrays.asList(AppTypeEnum.values()).stream()
                    .filter(app -> app.getValue().equals(smsNewTips.getAppType()))
                    .collect(Collectors.toList());

            if (list.size() < 1) {
                List<SmsApplication> applicationList = smsApplicationMapper.selectList(new LambdaQueryWrapper<SmsApplication>()
                        .eq(SmsApplication::getAppType, smsNewTips.getAppType()));
                if (applicationList != null && applicationList.size() > 0) {
                    appName = applicationList.get(0).getAppName();
                }
            }else{
                appName = list.get(0).getName();
            }

            MessageStepEnum messageStepEnum = MessageStepEnum.MESSAGE_STEP_ENUM_ALLOW_PASS;
            if (!allow_result) {
                messageStepEnum = MessageStepEnum.MESSAGE_STEP_ENUM_ALLOW_DENY;
            }

            weChatUtil.sendWXMPTemplateMessage(smsNewTips.getTipsCreator(),
                    smsNewTips.getTipsCreator(),
                    appName,
                    MessageEventEnum.MESSAGE_EVENT_ENUM_MSG,
                    messageStepEnum,
                    null);


            //发布消息通知
            List<String> personList = new ArrayList<>();
            personList.add(smsNewTips.getTipsCreator());
            List<AppTypeEnum> appTypeList = AppTypeEnum
                    .stream()
                    .filter(appTypeEnum -> appTypeEnum.getValue().equals(smsNewTips.getAppType()))
                    .collect(Collectors.toList());
            if (appTypeList.size() > 0) {
                addNewTips(TIPS_TYPE_ENUM_MESSAGE,
                        allow_user_id,
                        RANGE_TYPE_ENUM_PERSON,
                        personList,
                        appTypeList.get(0),
                        event_id,
                        allow_result ? TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_PASS :
                                TIPS_RECORD_STATUS_ENUM_ABOUT_ME_ALLOW_MESSAGE_DENY,
                        null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * 已有消息通知，结束待办类型的消息通知
     *
     * @param event_id       消息通知绑定的事件id  例：如消息类型为待办，则event_id就可能为问卷id
     * @param finish_user_id 完成当前待办事件的用户id
     */
    @Transactional
    public void dealFinishTips(String event_id,
                               String finish_user_id) {
        try {
            //查看消息是否存在且是否为待办消息类型 消息为开启状态
            SmsNewTips smsNewTips = smsNewTipsMapper.selectOne(new QueryWrapper<SmsNewTips>()
                    .lambda()
                    .eq(SmsNewTips::getEventId, event_id)
                    .eq(SmsNewTips::getIsClose, TIPS_OPEN));
            if (smsNewTips == null || isNullOrEmpty(smsNewTips.getId())
                    || smsNewTips.getTipsType() != TIPS_TYPE_ENUM_DEAL.getValue()) {
                return;
            }

            //查看操作人记录是否存在
            SmsNewTipsRecord smsNewTipsRecord = smsNewTipsRecordMapper.selectOne(new QueryWrapper<SmsNewTipsRecord>()
                    .lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordUserId, finish_user_id)
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue()));
            if (smsNewTipsRecord == null || isNullOrEmpty(smsNewTipsRecord.getId())) {
                return;
            }

            //修改操作人状态
            SmsNewTipsRecord updateTipsRecord = new SmsNewTipsRecord();
            updateTipsRecord.setId(smsNewTipsRecord.getId());
            updateTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_DEAL_FINISH.getValue());
            smsNewTipsRecordMapper.updateById(updateTipsRecord);

            //添加新消息通知
//            List<String> rangeList = new ArrayList<>();
//            rangeList.add(smsNewTips.getTipsCreator());
//            List<AppTypeEnum> appTypeList = AppTypeEnum
//                    .stream()
//                    .filter(appTypeEnum -> appTypeEnum.getValue().equals(smsNewTips.getAppType()))
//                    .collect(Collectors.toList());
//            if (appTypeList.size() > 0) {
//                addNewTips(TIPS_TYPE_ENUM_MESSAGE,
//                        finish_user_id,
//                        RANGE_TYPE_ENUM_PERSON,
//                        rangeList,
//                        appTypeList.get(0),
//                        smsNewTips.getEventId(),
//                        TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_MESSAGE,
//                        null);
//            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


    /**
     * 取消待办或取消审核流程调用该方法
     *
     * @param event_id 消息通知绑定的事件id  例：如消息类型为待办，则event_id就可能为问卷id
     */
    @Transactional
    public void cancelFinishTips(String event_id) {
        try {
            //查看消息是否开启状态
            SmsNewTips smsNewTips = smsNewTipsMapper.selectOne(new QueryWrapper<SmsNewTips>()
                    .lambda()
                    .eq(SmsNewTips::getEventId, event_id)
                    .eq(SmsNewTips::getIsClose, TIPS_OPEN)
                    .and(smsNewTipsLambdaQueryWrapper -> {
                        smsNewTipsLambdaQueryWrapper.isNull(SmsNewTips::getExpirationTime)
                                .or()
                                .gt(SmsNewTips::getExpirationTime, new Date());//未过期
                    })
            );
            if (smsNewTips == null || isNullOrEmpty(smsNewTips.getId())) {
                return;
            }

            //修改消息状态
            SmsNewTips updateNewTips = new SmsNewTips();
            updateNewTips.setId(smsNewTips.getId());
            updateNewTips.setIsClose(TIPS_CLOSE_FLAG_TRUE);
            smsNewTipsMapper.updateById(updateNewTips);

            //修改创建人状态(消息类型为审批时有效)
            SmsNewTipsRecord updateTipsRecord = new SmsNewTipsRecord();
            updateTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_CANCEL.getValue());
            smsNewTipsRecordMapper.update(updateTipsRecord, new QueryWrapper<SmsNewTipsRecord>()
                    .lambda()
                    .eq(SmsNewTipsRecord::getRecordUserId, smsNewTips.getTipsCreator())
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue()));

            //删除其他人未处理消息记录
            QueryWrapper<SmsNewTipsRecord> deleteQueryWrapper = new QueryWrapper<>();
            deleteQueryWrapper.lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .and(wrapper -> {
                        wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue())
//                                .or()
//                                .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue())
                        ;
                    });
            smsNewTipsRecordMapper.delete(deleteQueryWrapper);

            //修改待办消息为结束状态
            SmsNewTipsRecord updateRecord = new SmsNewTipsRecord();
            updateRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_DEAL_FINISH.getValue());
            QueryWrapper<SmsNewTipsRecord> updateQueryWrapper = new QueryWrapper<>();
            updateQueryWrapper.lambda()
                    .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                    .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue());
            smsNewTipsRecordMapper.update(updateRecord, updateQueryWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


    //超时置位
    @Transactional
    public void expiredStatusSetting() {
        try {
            List<SmsNewTips> tipsList = smsNewTipsMapper.selectList(new QueryWrapper<SmsNewTips>()
                    .lambda()
                    .eq(SmsNewTips::getIsClose, TIPS_CLOSE_FLAG_FALSE)
                    .lt(SmsNewTips::getExpirationTime, new Date()));
            if (tipsList != null && tipsList.size() > 0) {
                for (SmsNewTips smsNewTips : tipsList) {
                    SmsNewTips updateTips = new SmsNewTips();
                    updateTips.setId(smsNewTips.getId());
                    updateTips.setIsClose(TIPS_CLOSE_FLAG_TRUE);
                    smsNewTipsMapper.updateById(updateTips);

                    SmsNewTipsRecord smsNewTipsRecord = new SmsNewTipsRecord();
                    smsNewTipsRecord.setRecordStatus(TIPS_RECORD_STATUS_ENUM_EXPIRE.getValue());

                    QueryWrapper<SmsNewTipsRecord> updateQueryWrapper = new QueryWrapper<>();
                    updateQueryWrapper.lambda()
                            .eq(SmsNewTipsRecord::getRecordTipsId, smsNewTips.getId())
                            .and(wrapper -> {
                                wrapper.eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOW_WAIT_ME.getValue())
                                        .or()
                                        .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ABOUT_ME_DEAL_EVENT.getValue())
                                        .or()
                                        .eq(SmsNewTipsRecord::getRecordStatus, TIPS_RECORD_STATUS_ENUM_ALLOWING.getValue());
                            });
                    smsNewTipsRecordMapper.update(smsNewTipsRecord, updateQueryWrapper);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


}
